import { BasePlugin } from '../plugin-system/base-plugin.js'

/**
 * 自动补全插件
 * 提供代码自动补全功能
 */
export class AutoCompletePlugin extends BasePlugin {
    constructor(editor, options = {}) {
        super(editor, {
            // 默认配置
            triggerCharacters: ['a-zA-Z0-9_.'],
            debounceDelay: 300,
            maxItems: 20,
            ...options
        })
        
        // 状态管理
        this.completionItems = []
        this.filteredItems = []
        this.selectedIndex = 0
        this.currentFilter = ''
        
        // 防抖定时器
        this.completionTimer = null
    }
    
    initialize() {
        // 插件初始化逻辑
        // 自动补全弹窗功能已集成到插件中
    }
    
    onEnable() {
        // 监听编辑器事件
        this.editor.on('editor:input', this.handleInput.bind(this))
        this.editor.on('editor:keydown', this.handleKeyDown.bind(this))
        this.editor.on('editor:click', this.hideAutocomplete.bind(this))
        
        // 防止弹窗获取焦点时隐藏
        this.editor.autocompletePopupDom.addEventListener('mousedown', this.preventBlur)
        
        // 监听补全项点击事件
        this.editor.autocompleteList.addEventListener('click', this.handleItemClick.bind(this))
        
        this.emit('autocomplete:enabled')
    }
    
    onDisable() {
        // 移除事件监听
        this.editor.off('editor:input', this.handleInput.bind(this))
        this.editor.off('editor:keydown', this.handleKeyDown.bind(this))
        this.editor.off('editor:click', this.hideAutocomplete.bind(this))
        
        this.editor.autocompletePopupDom.removeEventListener('mousedown', this.preventBlur)
        this.editor.autocompleteList.removeEventListener('click', this.handleItemClick.bind(this))
        
        // 隐藏弹窗
        this.hideAutocomplete()
        
        this.emit('autocomplete:disabled')
    }
    
    onDestroy() {
        if (this.completionTimer) {
            clearTimeout(this.completionTimer)
        }
        this.hideAutocomplete()
    }
    
    /**
     * 处理输入事件
     */
    handleInput(data) {
        // 如果是撤销/重做操作，不触发补全
        if (data.isUndo || data.isRedo) {
            this.hideAutocomplete()
            return
        }
        
        const cursorPosition = this.editor.editor.selectionStart
        const textBeforeCursor = this.editor.editor.value.substring(0, cursorPosition)
        const lastChar = textBeforeCursor.slice(-1)
        
        // 检查是否是单字符输入（避免复制粘贴等操作触发补全）
        const inputType = data.inputType || 'insertText'
        const isTyping = inputType === 'insertText' && 
                        data.data && 
                        data.data.length === 1
        
        if (isTyping) {
            // 检查是否应该触发补全
            if (this.shouldTriggerCompletion(lastChar)) {
                this.requestCompletion()
            } else if (lastChar === ' ' || lastChar === ';' || lastChar === '(' || lastChar === ')') {
                this.hideAutocomplete()
            }
        } else {
            // 非打字输入（复制粘贴等），隐藏补全
            this.hideAutocomplete()
        }
    }
    
    /**
     * 处理键盘事件
     */
    handleKeyDown(data) {
        const e = data.event
        const isAutocompleteVisible = this.editor.autocompletePopupDom.style.display === 'block'
        
        if (isAutocompleteVisible && this.filteredItems.length > 0) {
            switch (e.key) {
                case 'Tab':
                case 'Enter':
                    e.preventDefault()
                    this.insertSelectedCompletion()
                    return true
                case 'ArrowUp':
                    e.preventDefault()
                    this.selectPreviousItem()
                    return true
                case 'ArrowDown':
                    e.preventDefault()
                    this.selectNextItem()
                    return true
                case 'Escape':
                    e.preventDefault()
                    this.hideAutocomplete()
                    return true
            }
        }
        
        // 如果没有处理任何事件，返回false
        return false
    }
    
    /**
     * 防止弹窗失去焦点
     */
    preventBlur(e) {
        e.preventDefault()
    }
    
    /**
     * 处理补全项点击事件
     */
    handleItemClick(e) {
        // 查找被点击的补全项
        const item = e.target.closest('.autocomplete-item')
        if (item && item.dataset.index !== undefined) {
            const index = parseInt(item.dataset.index)
            this.selectCompletionItem(index)
        }
    }
    
    /**
     * 检查是否应该触发补全
     */
    shouldTriggerCompletion(char) {
        // 先检查是否在字符串或注释中
        if (this.isInStringOrComment()) {
            return false
        }
        
        // 字母、数字、下划线触发补全
        if (/[a-zA-Z0-9_]/.test(char)) {
            return true
        }
        
        // 点号触发补全：只有在点号前有单词字符或 } ] ) 时才触发
        if (char === '.') {
            const cursorPosition = this.editor.editor.selectionStart
            // 检查点号前一个位置是否有有效字符（修正：应该是 cursorPosition - 2，因为 cursorPosition 已经是点号后的位置）
            return this.hasWordBeforeDot(cursorPosition - 2)
        }
        
        return false
    }
    
    /**
     * 请求代码补全
     */
    requestCompletion() {
        // 清除之前的定时器
        if (this.completionTimer) {
            clearTimeout(this.completionTimer)
        }
        
        // 防抖
        this.completionTimer = setTimeout(() => {
            const lspPlugin = this.editor.getPlugin('LSPClientPlugin')
            if (!lspPlugin || !lspPlugin.enabled) {
                return
            }
            
            const cursorPosition = this.editor.editor.selectionStart
            const text = this.editor.editor.value
            const lines = text.substring(0, cursorPosition).split('\n')
            const line = lines.length - 1
            const character = lines[lines.length - 1].length
            
            // 获取当前要过滤的文本
            this.currentFilter = this.getCurrentWord()
            
            // 请求补全
            const completions = lspPlugin.generateCompletions(text, line, character)
            this.handleCompletionResponse(completions)
        }, this.options.debounceDelay)
    }
    
    /**
     * 处理补全响应
     */
    handleCompletionResponse(completions) {
        if (completions && completions.length > 0) {
            this.completionItems = completions
            this.filteredItems = this.filterCompletions(completions, this.currentFilter)
            
            if (this.filteredItems.length > 0) {
                this.selectedIndex = 0
                this.showAutocomplete()
                this.emit('autocomplete:show', { items: this.filteredItems })
            } else {
                this.hideAutocomplete()
            }
        } else {
            this.hideAutocomplete()
        }
    }
    
    /**
     * 过滤补全项
     */
    filterCompletions(completions, filterText) {
        if (!filterText || filterText.length === 0) {
            return completions.slice(0, this.options.maxItems)
        }
        
        const filtered = completions.filter(item =>
            item.label.toLowerCase().startsWith(filterText.toLowerCase())
        )
        
        return filtered.slice(0, this.options.maxItems)
    }
    
    /**
     * 隐藏自动补全弹窗
     */
    hideAutocomplete() {
        if (this.editor.autocompletePopupDom) {
            this.editor.autocompletePopupDom.style.display = 'none'
            this.editor.autocompleteList.innerHTML = ''
        }
        this.completionItems = []
        this.filteredItems = []
        this.selectedIndex = 0
        this.currentFilter = ''
    }
    
    /**
     * 选择补全项
     */
    selectCompletionItem(index) {
        this.selectedIndex = index
        this.insertSelectedCompletion()
    }
    
    /**
     * 插入选中的补全项
     */
    insertSelectedCompletion() {
        if (this.filteredItems.length > 0 && this.selectedIndex < this.filteredItems.length) {
            const selectedItem = this.filteredItems[this.selectedIndex]
            const cursorPosition = this.editor.editor.selectionStart
            
            // 获取当前单词的起始位置
            let wordStart = cursorPosition
            for (let i = cursorPosition - 1; i >= 0; i--) {
                const char = this.editor.editor.value[i]
                if (/[a-zA-Z0-9_]/.test(char)) {
                    wordStart = i
                } else {
                    break
                }
            }
            
            // 插入补全内容
            const beforeText = this.editor.editor.value.substring(0, wordStart)
            const afterText = this.editor.editor.value.substring(cursorPosition)
            this.editor.editor.value = beforeText + selectedItem.label + afterText
            
            // 设置光标位置
            const newCursorPosition = wordStart + selectedItem.label.length
            this.editor.editor.selectionStart = this.editor.editor.selectionEnd = newCursorPosition
            
            // 清理状态
            this.hideAutocomplete()
            
            // 手动触发输入事件，确保编辑器状态正确更新
            this.editor._updateEditor()
            this.editor._updateStatus()
            
            // 发射补全插入事件
            this.emit('autocomplete:insert', { item: selectedItem })
        }
    }
    
    /**
     * 选择上一个补全项
     */
    selectPreviousItem() {
        if (this.filteredItems.length > 0) {
            this.selectedIndex = (this.selectedIndex - 1 + this.filteredItems.length) % this.filteredItems.length
            this.renderList()
        }
    }
    
    /**
     * 选择下一个补全项
     */
    selectNextItem() {
        if (this.filteredItems.length > 0) {
            this.selectedIndex = (this.selectedIndex + 1) % this.filteredItems.length
            this.renderList()
        }
    }
    
    /**
     * 发射事件的便捷方法
     */
    emit(event, data) {
        this.editor.emit(event, data)
    }
    
    /**
     * 获取当前正在输入的单词
     */
    getCurrentWord() {
        if (!this.editor.editor) return ''
        
        const cursorPosition = this.editor.editor.selectionStart
        if (cursorPosition === undefined) return ''
        
        const text = this.editor.editor.value
        
        // 从光标位置向前查找单词边界
        let word = ''
        for (let i = cursorPosition - 1; i >= 0; i--) {
            const char = text[i]
            if (/[a-zA-Z0-9_]/.test(char)) {
                word = char + word
            } else {
                // 遇到非单词字符就停止（包括点号、空格等）
                break
            }
        }
        return word
    }
    
    /**
     * 显示自动补全弹窗
     */
    showAutocomplete() {
        if (!this.editor.autocompletePopupDom || !this.filteredItems.length) {
            return
        }
        
        // 更新计数
        if (this.editor.completionCount) {
            this.editor.completionCount.textContent = `${this.filteredItems.length} 项`
        }
        
        // 渲染列表
        this.renderList()
        
        // 更新位置
        this.updatePosition()
        
        // 显示弹窗
        this.editor.autocompletePopupDom.style.display = 'block'
    }
    
    /**
     * 渲染补全列表
     */
    renderList() {
        if (!this.editor.autocompleteList) return
        
        this.editor.autocompleteList.innerHTML = ''
        
        if (!this.filteredItems || this.filteredItems.length === 0) {
            return
        }
        
        const fragment = document.createDocumentFragment()
        
        this.filteredItems.forEach((item, index) => {
            const isSelected = index === this.selectedIndex
            const iconChar = this.getCompletionIcon(item.kind)
            const iconClass = this.getIconClass(item.kind)
            const highlightedLabel = this.highlightMatch(item.label, this.currentFilter)
            
            // 创建 DOM 元素
            const itemDiv = document.createElement('div')
            itemDiv.className = `autocomplete-item ${isSelected ? 'selected' : ''}`
            itemDiv.dataset.index = index
            
            const iconSpan = document.createElement('span')
            iconSpan.className = `autocomplete-icon icon-${iconClass}`
            iconSpan.textContent = iconChar
            
            const labelDiv = document.createElement('div')
            labelDiv.className = 'autocomplete-label'
            labelDiv.innerHTML = highlightedLabel
            
            const detailSpan = document.createElement('span')
            detailSpan.className = 'autocomplete-detail'
            detailSpan.textContent = item.detail || ''
            
            // 组装元素
            itemDiv.appendChild(iconSpan)
            itemDiv.appendChild(labelDiv)
            itemDiv.appendChild(detailSpan)
            
            fragment.appendChild(itemDiv)
        })
        
        this.editor.autocompleteList.appendChild(fragment)
        this.scrollToSelectedItem()
    }
    
    /**
     * 更新弹窗位置
     */
    updatePosition() {
        if (!this.editor.autocompletePopupDom || !this.editor.editor) return
        
        const cursorPosition = this.editor.editor.selectionStart
        const coords = this.getTextAreaCursorCoords(cursorPosition)
        const textareaRect = this.editor.editor.getBoundingClientRect()
        
        // 计算弹窗位置（相对于视口）
        const popupTop = textareaRect.top + coords.top + coords.height
        const popupLeft = textareaRect.left + coords.left
        
        // 应用位置
        this.editor.autocompletePopupDom.style.position = 'fixed'
        this.editor.autocompletePopupDom.style.top = popupTop + 'px'
        this.editor.autocompletePopupDom.style.left = popupLeft + 'px'
        
        // 调整位置以适应视口
        this.adjustPosition()
    }
    
    /**
     * 获取光标坐标
     */
    getTextAreaCursorCoords(position) {
        const computedStyle = getComputedStyle(this.editor.editor)
        const fontSize = parseInt(computedStyle.fontSize)
        const lineHeight = parseInt(computedStyle.lineHeight) || fontSize * 1.5
        const paddingLeft = parseInt(computedStyle.paddingLeft) || 0
        const paddingTop = parseInt(computedStyle.paddingTop) || 0
        
        const text = this.editor.editor.value
        const textBeforeCursor = text.substring(0, position)
        const lines = textBeforeCursor.split('\n')
        const lineCount = lines.length
        const lastLineText = lines[lines.length - 1] || ''
        
        // 计算字符宽度
        const charWidth = this.getCharWidth()
        
        return {
            top: (lineCount - 1) * lineHeight + paddingTop,
            left: lastLineText.length * charWidth + paddingLeft,
            height: lineHeight
        }
    }
    
    /**
     * 获取字符宽度
     */
    getCharWidth() {
        const testDiv = document.createElement('div')
        testDiv.style.position = 'absolute'
        testDiv.style.visibility = 'hidden'
        testDiv.style.fontFamily = getComputedStyle(this.editor.editor).fontFamily
        testDiv.style.fontSize = getComputedStyle(this.editor.editor).fontSize
        testDiv.style.whiteSpace = 'pre'
        testDiv.textContent = 'M'
        document.body.appendChild(testDiv)
        const width = testDiv.offsetWidth
        document.body.removeChild(testDiv)
        return width
    }
    
    /**
     * 调整弹窗位置以适应视口
     */
    adjustPosition() {
        if (!this.editor.autocompletePopupDom) return
        
        const popupRect = this.editor.autocompletePopupDom.getBoundingClientRect()
        const viewportWidth = window.innerWidth
        const viewportHeight = window.innerHeight
        
        let newTop = parseInt(this.editor.autocompletePopupDom.style.top)
        let newLeft = parseInt(this.editor.autocompletePopupDom.style.left)
        let adjusted = false
        
        // 检查右侧是否超出
        if (popupRect.right > viewportWidth) {
            newLeft = Math.max(10, newLeft - (popupRect.right - viewportWidth) - 10)
            adjusted = true
        }
        // 检查底部是否超出
        if (popupRect.bottom > viewportHeight) {
            newTop = newTop - popupRect.height - 25
            adjusted = true
        }
        // 检查左侧是否超出
        if (popupRect.left < 0) {
            newLeft = 10
            adjusted = true
        }
        // 检查顶部是否超出
        if (popupRect.top < 0) {
            newTop = newTop + 25
            adjusted = true
        }
        
        // 如果调整了位置，更新样式
        if (adjusted) {
            this.editor.autocompletePopupDom.style.top = newTop + 'px'
            this.editor.autocompletePopupDom.style.left = newLeft + 'px'
        }
    }
    
    /**
     * 滚动到选中的项目
     */
    scrollToSelectedItem() {
        if (this.filteredItems.length === 0 || !this.editor.autocompleteList) return
        
        const selectedItem = this.editor.autocompleteList.querySelector('.autocomplete-item.selected')
        if (!selectedItem) return
        
        const itemTop = selectedItem.offsetTop
        const itemBottom = itemTop + selectedItem.offsetHeight
        const listScrollTop = this.editor.autocompleteList.scrollTop
        const listHeight = this.editor.autocompleteList.clientHeight
        
        if (itemBottom > listScrollTop + listHeight) {
            this.editor.autocompleteList.scrollTop = itemBottom - listHeight + 5
        }
        if (itemTop < listScrollTop) {
            this.editor.autocompleteList.scrollTop = itemTop - 5
        }
    }
    
    /**
     * 获取补全项图标
     */
    getCompletionIcon(kind) {
        const icons = {
            2: '⨍', // Method
            3: '⨍', // Function
            6: '🔷', // Class/Object
            11: '🔢', // Value/Constant
            14: '🔤'  // Keyword
        }
        return icons[kind] || '📝'
    }
    
    /**
     * 获取图标CSS类
     */
    getIconClass(kind) {
        const classes = {
            2: 'method',
            3: 'function',
            6: 'class',
            11: 'variable',
            14: 'keyword'
        }
        return classes[kind] || 'variable'
    }
    
    /**
     * 高亮匹配的文本
     */
    highlightMatch(label, filterText) {
        if (!filterText || filterText.length === 0) {
            return label
        }
        const index = label.toLowerCase().indexOf(filterText.toLowerCase())
        if (index === -1) {
            return label
        }
        const before = label.substring(0, index)
        const match = label.substring(index, index + filterText.length)
        const after = label.substring(index + filterText.length)
        return `${before}<span class="highlight-match">${match}</span>${after}`
    }
    
    /**
     * 检查当前光标是否在字符串或注释中
     */
    isInStringOrComment() {
        const cursorPosition = this.editor.editor.selectionStart
        const text = this.editor.editor.value
        const textBeforeCursor = text.substring(0, cursorPosition)
        
        // 检查是否在字符串中
        let inString = false
        let stringChar = ''
        let escaped = false
        
        for (let i = 0; i < textBeforeCursor.length; i++) {
            const char = textBeforeCursor[i]
            
            if (escaped) {
                escaped = false
                continue
            }
            
            if (char === '\\' && inString) {
                escaped = true
                continue
            }
            
            if ((char === '"' || char === "'" || char === '`') && !inString) {
                inString = true
                stringChar = char
            } else if (char === stringChar && inString) {
                inString = false
                stringChar = ''
            }
        }
        
        if (inString) {
            return true
        }
        
        // 检查是否在注释中
        const currentLine = textBeforeCursor.split('\n').pop() || ''
        if (currentLine.includes('//')) {
            return true
        }
        
        // 检查多行注释
        const commentStart = textBeforeCursor.lastIndexOf('/*')
        const commentEnd = textBeforeCursor.lastIndexOf('*/')
        if (commentStart > commentEnd) {
            return true
        }
        
        return false
    }
    
    /**
     * 检查点号前是否有单词
     */
    hasWordBeforeDot(position) {
        if (position < 0) return false
        
        const text = this.editor.editor.value
        
        // 向前查找非空白字符
        for (let i = position; i >= 0; i--) {
            const char = text[i]
            
            if (/\s/.test(char)) {
                continue
            }
            // 如果找到字母、数字或下划线，说明有单词
            if (/[a-zA-Z0-9_}\]]/.test(char)) {
                return true
            }
            // 其他字符说明没有单词
            return false
        }
        
        return false
    }
}